package com.zsrt.javaweb.ch02;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

/**
 * 对数学计算器ArithmeticCalculate进行日志代理
 * @author Administrator
 *
 */
public class ArithmeticCalculateLoggingProxy {
	
	/**
	 * 目标对象[被代理的对象]
	 */
	private ArithmeticCalculate target;
	
	
	/**
	 * 给属性赋值
	 * @param target
	 */
	public ArithmeticCalculateLoggingProxy(ArithmeticCalculate target) {
		this.target = target;
	}

	/**
	 * 得到代理对象[得到目标对象的代理对象]
	 * @return
	 */
	public ArithmeticCalculate getProxy(){
		
		ArithmeticCalculate proxy= null;
		
		//代理对象由哪一个类加载器进行加载
		ClassLoader loader=target.getClass().getClassLoader();
		
		//目标对象实现的接口
		Class<?>[] interfaces = target.getClass().getInterfaces();
		
		//Class<?>[] interfaces = new Class[]{ArithmeticCalculate.class};
		
		//回调函数 匿名内部类
		InvocationHandler h = new InvocationHandler(){
			
			/**
			 * proxy: 指的是正在返回的那个代理对象。一般情况下 。在invoke方法中都不使用该对象  否则会出现死循环
			 * method ：正在被调用的方法
			 * args  ：  调用目标对象的某个方法 传入的参数
			 */
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				
				//System.out.println(proxy);
				System.out.println("执行回调函数中的方法....");
				
				//记录日志
				System.out.println("scott 进入"+method.getName()+"方法... 方法的参数为："+ Arrays.asList(args));
				
				//执行方法
				Object jieguo = method.invoke(target, args);
				
				//记录日志
				System.out.println("scott "+method.getName()+"方法的返回值为:"+jieguo);
				return jieguo;
			}
			
		} ;
		
		//注意：代理对象不是直接new出来的 是通过代理并强转过来的
		proxy = (ArithmeticCalculate) Proxy.newProxyInstance(loader, interfaces, h);
		return proxy;
		
	}
	
	
	

}
